using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Web;
using NopSolutions.NopCommerce.BusinessLogic.Products;
using NopSolutions.NopCommerce.BusinessLogic.Products.Specs;
using NopSolutions.NopCommerce.Common.Utils;

namespace NopSolutions.NopCommerce.LuceneHelper
{
    public class FilterContext
    {
        private IList<SpecificationAttributeOption> _filters = new List<SpecificationAttributeOption>();
        private IList<int> _categories = new List<int>();
        private IList<int> _manufacturers = new List<int>();
        private ProductsSortBy _productSortBy = ProductsSortBy.Relevance;
        private PriceRange _priceRange = null;
        private string keyWords = string.Empty;

        public FilterContext(NameValueCollection request)
        {
            decimal? from = null;
            decimal? to = null;
            foreach (string key in request.Keys)
            {
                if (!string.IsNullOrEmpty(key))
                {
                    string value = request[key].ToLower();
                    if (key.StartsWith("attr"))
                    {
                        var attrFilter =
                            SpecificationAttributeManager.GetSpecificationAttributeOptionById(int.Parse(value));
                        //attrFilter.SpecificationAttributeId = int.Parse(key.Replace("attr", ""));
                        //attrFilter.SpecificationAttributeOptionId = ;
                        _filters.Add(attrFilter);
                    }
                    else if (key.ToLower().Equals("categoryid"))
                    {
                        _categories.Add(int.Parse(value));
                    }
                    else if (key.ToLower().Equals("manufacturerid"))
                    {
                        _manufacturers.Add(int.Parse(value));
                    }
                    else if (key.ToLower().Equals("sortby"))
                    {
                        switch (value)
                        {
                            case Globals.SORTBY_RELEVANCE:
                                _productSortBy = ProductsSortBy.Relevance;
                                break;
                            case Globals.SORTBY_HIGHEST_RATED:
                                _productSortBy = ProductsSortBy.HighestRated;
                                break;
                            case Globals.SORTBY_BEST_SELLING:
                                _productSortBy = ProductsSortBy.DisplayOrder;
                                break;
                            case Globals.SORTBY_PRICE_LOW_TO_HIGH:
                                _productSortBy = ProductsSortBy.PriceAsc;
                                break;
                            case Globals.SORTBY_PRICE_HIGH_TO_LOW:
                                _productSortBy = ProductsSortBy.PriceDesc;
                                break;
                            case Globals.SORTBY_BRAND_AZ:
                                _productSortBy = ProductsSortBy.BrandAsc;
                                break;
                            case Globals.SORTBY_BRAIN_ZA:
                                _productSortBy = ProductsSortBy.BrandDesc;
                                break;
                            default:
                                _productSortBy = ProductsSortBy.Relevance;
                                break;
                        }
                    }
                    else if (key.ToLower().Equals("from"))
                    {
                        decimal i = 0;
                        if (decimal.TryParse(value, out i))
                        {
                            from = i;
                        }
                    }
                    else if (key.ToLower().Equals("to"))
                    {
                        decimal i = 0;
                        if (decimal.TryParse(value, out i))
                        {
                            to = i;
                        }
                    }
                    else if (key.ToLower().Equals("searchterms"))
                    {
                        keyWords = HttpUtility.UrlDecode(value);
                    }
                }
            }
            if (from.HasValue || to.HasValue)
            {
                _priceRange = new PriceRange { From = from, To = to };
            }
        }

        public FilterContext()
        {

        }

        public void RedirectToFilteredPage(string currentUrl)
        {
            currentUrl = ModifyUrlCategories(currentUrl);
            currentUrl = ModifyUrlManufacturers(currentUrl);
            currentUrl = ModifyUrlKeywords(currentUrl);
            currentUrl = ModifyUrlPriceRange(currentUrl);
            currentUrl = ModifyUrlSpecificationFilters(currentUrl);
            HttpContext.Current.Response.Redirect(currentUrl);
        }

        public void RedirectToFilteredPage()
        {
            RedirectToFilteredPage(CommonHelper.GetThisPageUrl(true));
        }



        private static Dictionary<string, string> GetUrlQueries(string url)
        {
            var dictionary = new Dictionary<string, string>();

            if (url == null)
                url = string.Empty;
            url = url.ToLowerInvariant();


            string str = string.Empty;
            if (url.Contains("?"))
            {
                str = url.Substring(url.IndexOf("?") + 1);
                url = url.Substring(0, url.IndexOf("?"));
            }
            if (!string.IsNullOrEmpty(str))
            {
                
                foreach (string str3 in str.Split(new char[] { '&' }))
                {
                    if (!string.IsNullOrEmpty(str3))
                    {
                        string[] strArray = str3.Split(new char[] { '=' });
                        if (strArray.Length == 2)
                        {
                            dictionary[strArray[0]] = strArray[1];
                        }
                        else
                        {
                            dictionary[str3] = null;
                        }
                    }
                }


            }

            return dictionary;
        }

        public string ModifyUrlKeywords(string url)
        {
            return ModifyUrlKeywords(url, keyWords);
        }

        public static string ModifyUrlKeywords(string url, string keywords)
        {
            return !string.IsNullOrEmpty(keywords) ? url.ModifyQueryString("searchTerms", keywords) : url.RemoveQueryString("searchTerms");
        }

        public static string ModifyUrlCategories(string url, IList<int> categories)
        {
            return categories.Count > 0 ? url.ModifyQueryString("CategoryID", categories.ToDelimitedString()) : url.RemoveQueryString("CategoryID");
        }

        public string ModifyUrlCategories(string url)
        {
            return ModifyUrlCategories(url, _categories);
        }

        public static string ModifyUrlManufacturers(string url, IList<int> manufacturers)
        {
            return manufacturers.Count > 0 ? url.ModifyQueryString("ManufacturerID", manufacturers.ToDelimitedString()) : url.RemoveQueryString("ManufacturerID");
        }

        public string ModifyUrlManufacturers(string url)
        {
            return ModifyUrlManufacturers(url, _manufacturers);
        }

        public static string ModifyUrlSpecificationFilters(string url, IList<SpecificationAttributeOption> specificationOptions)
        {
            var queriesToRemove = from query in GetUrlQueries(url)
                                  where query.Key.ToLower().StartsWith("attr")
                                  select query;
            if (specificationOptions.Count > 0)
            {
                url = queriesToRemove.Aggregate(url,
                                                (current, queryToRemove) =>
                                                current.RemoveQueryString(queryToRemove.Key));
            }
            return url;
        }

        public string ModifyUrlSpecificationFilters(string url)
        {
            return ModifyUrlSpecificationFilters(url, _filters);
        }

        public string ModifyUrlPriceRange(string url)
        {
            return ModifyUrlPriceRange(url, _priceRange);
        }
        
        public static string ModifyUrlPriceRange(string url, PriceRange priceRange)
        {
            if (priceRange != null && (priceRange.From.HasValue || priceRange.To.HasValue))
            {
                string fromQuery = string.Empty;
                if (priceRange.From.HasValue)
                {
                    fromQuery = priceRange.From.Value.ToString(new CultureInfo("en-US"));
                }
                string toQuery = string.Empty;
                if (priceRange.To.HasValue)
                {
                    toQuery = priceRange.To.Value.ToString(new CultureInfo("en-US"));
                }

                url.ModifyQueryString("from=" + fromQuery + "&to=" + toQuery);
            }
            return url.RemoveQueryString("from").RemoveQueryString("to");
        }

        public IList<SpecificationAttributeOption> Filters
        {
            get { return _filters; }
        }

        public IList<int> Categories
        {
            get { return _categories; }
            set { _categories = value; }
        }

        public IList<int> Manufacturers
        {
            get { return _manufacturers; }
            set { _manufacturers = value; }
        }

        public ProductsSortBy ProductSortBy
        {
            get { return _productSortBy; }
            set { _productSortBy = value; }
        }
        public PriceRange PriceRange
        {
            get { return _priceRange; }
            set { _priceRange = value; }
        }
        public string KeyWords
        {
            get { return keyWords; }
            set { keyWords = value; }
        }
    }
}
